package com.zenithmind.common.config;

import com.zenithmind.common.utils.ConfigEncryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.HashMap;
import java.util.Map;

/**
 * 加密配置属性后处理器
 * 在应用启动时自动解密配置文件中的加密属性
 */
@Slf4j
public class EncryptedPropertySourcePostProcessor implements EnvironmentPostProcessor {
    
    private static final String ENCRYPTED_PROPERTY_SOURCE_NAME = "encryptedProperties";
    
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        log.info("开始处理加密配置属性");
        
        MutablePropertySources propertySources = environment.getPropertySources();
        Map<String, Object> decryptedProperties = new HashMap<>();
        
        // 遍历所有属性源
        for (PropertySource<?> propertySource : propertySources) {
            if (propertySource.getSource() instanceof Map) {
                @SuppressWarnings("unchecked")
                Map<String, Object> source = (Map<String, Object>) propertySource.getSource();
                
                for (Map.Entry<String, Object> entry : source.entrySet()) {
                    String key = entry.getKey();
                    Object value = entry.getValue();
                    
                    if (value instanceof String) {
                        String stringValue = (String) value;
                        if (ConfigEncryptUtils.isEncrypted(stringValue)) {
                            try {
                                String decryptedValue = ConfigEncryptUtils.decrypt(stringValue);
                                decryptedProperties.put(key, decryptedValue);
                                log.debug("解密配置属性: {}", key);
                            } catch (Exception e) {
                                log.error("解密配置属性失败: {}", key, e);
                                // 解密失败时保持原值
                                decryptedProperties.put(key, stringValue);
                            }
                        }
                    }
                }
            }
        }
        
        // 如果有解密的属性，添加到属性源中
        if (!decryptedProperties.isEmpty()) {
            PropertySource<Map<String, Object>> encryptedPropertySource = 
                new MapPropertySource(ENCRYPTED_PROPERTY_SOURCE_NAME, decryptedProperties);
            
            // 将解密的属性源添加到最高优先级
            propertySources.addFirst(encryptedPropertySource);
            
            log.info("成功处理 {} 个加密配置属性", decryptedProperties.size());
        } else {
            log.info("未发现需要解密的配置属性");
        }
    }
}
